
import { DateTimeCore } from './DateTimeCore';
import { isLeapYear as isLeapYearHelper, getDaysInMonth as getDaysInMonthHelper } from '../helpers';

/**
 * 日期时间获取类
 * @class DateTimeGetter
 * @description 提供获取日期时间各组成部分的方法，用于提取年、月、日、时、分、秒等日期时间元素
 */
export class DateTimeGetter {
  /**
   * DateTimeCore实例，提供基础日期时间操作
   * @private
   */
  private __core: DateTimeCore;

  /**
   * 构造函数
   * @param {DateTimeCore} core - DateTimeCore实例
   * @returns {DateTimeGetter} 新的DateTimeGetter实例
   */
  constructor(core: DateTimeCore) {
    this.__core = core;
  }

  /**
   * 获取年份
   * @returns {number} 四位数年份（如：2025）
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * const year = date.getter.year(); // 2025
   */
  year(): number {
    return this.__core.dayjs().year();
  }

  /**
   * 获取月份
   * @returns {number} 月份，范围1-12
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * const month = date.getter.month(); // 12
   */
  month(): number {
    return this.__core.dayjs().month() + 1; // dayjs的month()返回0-11，需要+1转换为1-12
  }

  /**
   * 获取日期（1-31）
   * @returns {number} 日期（1-31）
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * date.getter.day(); // 11
   */
  day(): number {
    return this.__core.dayjs().day();
  }

  /**
   * 获取小时
   * @returns {number} 小时，范围0-23
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * const hour = date.getter.hour(); // 14
   */
  hour(): number {
    return this.__core.dayjs().hour();
  }

  /**
   * 获取分钟
   * @returns {number} 分钟，范围0-59
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * const minute = date.getter.minute(); // 30
   */
  minute(): number {
    return this.__core.dayjs().minute();
  }

  /**
   * 获取秒数
   * @returns {number} 秒数，范围0-59
   * @example
   * const date = new DateTime('2025-12-11 14:30:45');
   * const second = date.getter.second(); // 45
   */
  second(): number {
    return this.__core.dayjs().second();
  }

  /**
   * 获取毫秒数
   * @returns {number} 毫秒数，范围0-999
   * @example
   * const date = new DateTime('2025-12-11 14:30:45.123');
   * const millisecond = date.getter.millisecond(); // 123
   */
  millisecond(): number {
    return this.__core.dayjs().millisecond();
  }

  /**
   * 获取当前月份的天数
   * @returns {number} 当月天数，范围28-31
   * @example
   * const date = new DateTime('2024-02-01');
   * const daysInMonth = date.getter.daysInMonth(); // 29（闰年2月）
   * 
   * const date2 = new DateTime('2023-02-01');
   * const daysInMonth2 = date2.getter.daysInMonth(); // 28（非闰年2月）
   */
  daysInMonth(): number {
    return this.__core.dayjs().daysInMonth();
  }

  /**
   * 获取星期几
   * @returns {number} 星期几，范围0-6，0代表星期日，1-6代表星期一至星期六
   * @example
   * const date = new DateTime('2025-12-11');
   * const dayOfWeek = date.getter.dayOfWeek(); // 0（假设是星期日）
   */
  dayOfWeek(): number {
    return this.__core.dayjs().day();
  }

  /**
   * 获取季度
   * @returns {number} 季度，范围1-4，1代表第一季度，4代表第四季度
   * @example
   * const date = new DateTime('2025-12-11');
   * const quarter = date.getter.quarter(); // 4
   */
  quarter(): number {
    // 计算季度：1-3月为第一季度，4-6月为第二季度，以此类推
    const month = this.__core.dayjs().month(); // 0-11
    return Math.floor(month / 3) + 1;
  }

  /**
   * 判断当前日期是否是闰年
   * @returns {boolean} 如果是闰年返回true，否则返回false
   * @example
   * const date1 = new DateTime('2024-01-01');
   * const isLeapYear1 = date1.getter.isLeapYear(); // true
   * 
   * const date2 = new DateTime('2023-01-01');
   * const isLeapYear2 = date2.getter.isLeapYear(); // false
   */
  isLeapYear(): boolean {
    return isLeapYearHelper(this.year());
  }

  /**
   * 获取指定月份的天数
   * @param {number} [month] - 可选的月份（1-12），如果不指定则使用当前日期的月份
   * @returns {number} 指定月份的天数
   * @throws {Error} 当指定的月份为2但无法确定年份时抛出错误
   * @example
   * const date = new DateTime('2024-01-01');
   * 
   * // 获取当前月份（1月）的天数
   * const daysInCurrentMonth = date.getter.getDaysInMonth(); // 31
   * 
   * // 获取指定月份（2月）的天数，使用当前日期的年份（2024）
   * const daysInFebruary = date.getter.getDaysInMonth(2); // 29（闰年）
   * 
   * // 获取其他月份的天数
   * const daysInApril = date.getter.getDaysInMonth(4); // 30
   */
  getDaysInMonth(): number {
    return getDaysInMonthHelper(this.month(), this.year());
  }
}